﻿/*----------------------------------------------------------*
 *                       Ball Class                        *
 *                                                          *
 *                Created By: Matthew Hoyes                 *
 *                                                          *
 *      This class will eventually serve as an Abstract     *
 *      Class which all other types/colors of balls         *
 *      will inherit from, overloading the base methods.    *
 *----------------------------------------------------------*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework.Graphics; // For Texture2D
using Microsoft.Xna.Framework;          // For Vector2



namespace BrickBreaker
{
    enum BallState { IDLE, ACTIVE, DEAD };
    
    class BBBall
    {
        /* private Texture variable */
        private Texture2D texture;      // V001: Ball texture
        
        /* private Vector2 variables */
        private Vector2 position;       // V002: Balls position on screen
        private Vector2 size;           // V003: Balls size in pixels
        private Vector2 screenSize;     // V004: Screen size
        private Vector2 velocity;       // V005: Balls velocity
        private Vector2 center;         // V006: Balls center position
        private Vector2 startPosition;  // V007: Stores the start position of the ball
        
        /* private float variables */
        private float radius;           // V008: Balls radius
        private float scale;            // V009: Balls scale

        /* private int variables */
        private int lives;              // V010: How many lives/balls until game over?

        /* private bool variables */
        private bool canMove;           // V011: Can the ball move?
        private bool bAlive;            // V012: Is the ball alive?
        private bool launched;          // V013: Has the ball launched from the paddle?

        /* private state variable */
        private BallState ballState;    // V014: The balls current state
        
        /* M001: Default Constructor */
        public BBBall(Texture2D newTexture, Vector2 newPosition, Vector2 newSize, 
                     float Scale, int ScreenWidth, int ScreenHeight)
        {
            texture = newTexture;
            position = newPosition;
            size = newSize * new Vector2(scale, scale) ;
            scale = Scale;
            screenSize = new Vector2(ScreenWidth, ScreenHeight);
            startPosition = newPosition;

            canMove = false;
            bAlive = true;
            launched = false;
            lives = 3;              // CHANGE HARD CODE STATE LATER

            ballState = BallState.IDLE;
        }

        /* M002: */
        public void setPosition(Vector2 pos)
        {
            position = pos;
        }

        /* M003: */
        public Vector2 getPosition()
        {
            return position;
        }

        /* M004: */
        public void setSize(Vector2 Size)
        {
            size = Size;
        }

        /* M005: */
        public Vector2 getSize()
        {
            return size;
        }

        /* M006: */
        public void setScreenSize(Vector2 ScreenSize)
        {
            screenSize = ScreenSize;
        }

        /* M007: */
        public Vector2 getScreenSize()
        {
            return screenSize;
        }

        /* M008: */
        public void setVelocity(Vector2 Velocity)
        {
            velocity = Velocity;
        }

        /* M009: */
        public Vector2 getVelocity()
        {
            return velocity;
        }

        /* this method not needed
         * ----------------------
        public void setCenter(Vector2 Center)
        {
            center = Center;
        }
        */

        /* M010: */
        public Vector2 getCenter()
        {
            center = position + (size / 2);
            return center;
        }

        /* M011: */
        public void setStartPosition(Vector2 Position)
        {
            startPosition = Position;
        }

        /* M012: */
        public Vector2 getStartPosition()
        {
            return startPosition;
        }

        /* M013: */
        public float getRadius()
        {
            radius = (size.X / 2);
            return radius;
        }

        /* M014: */
        public void setScale(float Scale)
        {
            scale = Scale;
        }

        /* M015: */
        public float getScale()
        {
            return scale;
        }

        /* M016: */
        public void setLives(int numberOfLives)
        {
            lives = numberOfLives;
        }

        /* M017: */
        public int getLives()
        {
            return lives;
        }

        /* M018: */
        public void setCanMove(bool ableToMove)
        {
            canMove = ableToMove;
        }

        /* M019: */
        public bool getCanMove()
        {
            return canMove;
        }

        /* M020: */
        public void setAliveState(bool isAlive)
        {
            bAlive = isAlive;
        }

        /* M021: */
        public bool getAliveState()
        {
            return bAlive;
        }

        /* M022: */
        public void setHasLaunched(bool hasLaunched)
        {
            launched = hasLaunched;
        }

        /* M023: */
        public bool getHasLaunched()
        {
            return launched;
        }

        /*      M024: Draw Method      *
         * Displays the ball on screen */
        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(texture, position, null, Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, 0f);
        }

        /*     M025: Move Method    *
         * Moves the ball on screen */
        public void Move()
        {
            // If we'll move out of the screen, invert velocity
            // Checking right boundary
            if (position.X + size.X + velocity.X > screenSize.X)
            {
                velocity = new Vector2(-velocity.X, velocity.Y);
            }

            // Checking left boundary
            if (position.X + velocity.X < 0)
            {
                velocity = new Vector2(-velocity.X, velocity.Y);
            }

            // Checking upper boundary
            if (position.Y + velocity.Y < 0)
            {
                velocity = new Vector2(velocity.X, -velocity.Y);
            }

            // Since we adjusted the velocity, just add it to the current position
            position += velocity;
        }

        /*     M026: Collides Method    *
         * Checks whether the ball has  *
         * collided with the paddle     */
        //public bool Collides(Paddle thePaddle)
        //{
        //    // Check if two sprites collide          
        //    if(this.position.X >= thePaddle.getPositionX() - thePaddle.getSizeX() &&
        //       this.position.X <= thePaddle.getPositionX() + thePaddle.getSizeX() &&
        //       this.position.Y >= thePaddle.getPositionY() - thePaddle.getSizeY() &&
        //       this.position.Y <= thePaddle.getPositionY() + thePaddle.getSizeY())
        //    {
        //        return true;
        //    }
        //    else
        //    {
        //        return false;
        //    }
        //}

        /*     M027: Collides Method    *
         * Checks whether the ball has  *
         * collided with a brick        */
        //public bool Collides(Brick theBrick)
        //{
        //    // Check if two sprites collide          
        //    if (this.position.X >= theBrick.getPositionX() - theBrick.getSizeX() &&
        //        this.position.X <= theBrick.getPositionX() + theBrick.getSizeX() &&
        //        this.position.Y >= theBrick.getPositionY() - theBrick.getSizeY() &&
        //        this.position.Y <= theBrick.getPositionY() + theBrick.getSizeY())
        //    {
        //        return true;
        //    }
        //    else
        //    {
        //        return false;
        //    }
        //}

        /*     M028: Collides Method    *
         * Checks whether the ball has  *
         * collided with another ball   */
        //public bool Collides(Ball otherBall)
        //{
        //    // Check if two circle sprites collided
        //    return (Vector2.Distance(this.center, otherBall.center) < this.radius + otherBall.radius);
        //}

        /*     M029: isDead Method      *
         * Checks whether the ball has  *
         * died or not                  */
        public bool isDead()
        {
            if (this.position.Y + this.size.Y + this.velocity.Y > this.screenSize.Y)
            {
                this.lives--;

                return true;
            }

            return false;
        }

        /*     M030: hasLives Method    *
         * Checks whether the ball has  *
         * any more lives               */
        public bool hasLives()
        {
            if(this.lives > 0)
            {
                return true;
            }

            return false;
        }

        /*      M031: Reset Method         *
         * Resets all the balls variables  */
        public void Reset()
        {
            this.position = this.startPosition;
            this.canMove = false;
            this.launched = false;
        }

        /* M032: Delete Method  *
         * Deletes the object   */
        public void Delete()
        {
            this.texture.Dispose();
        }

        public void setState(BallState state)
        {
            ballState = state;
        }

        public BallState getState()
        {
            return ballState;
        }
    }
}
